module handshake_pipe (
    input wire clk,
    input wire rst,

    input  wire        master_valid,
    input  wire [31:0] master_data,
    output wire        master_ready,

    output wire        slave_valid,
    output wire [31:0] slave_data,
    input  wire        slave_ready
    );

    reg ready_reg;
    always @(posedge clk) begin
        if(rst) begin
            ready_reg <= 1'b0;
        end
        else begin
            ready_reg <= slave_ready | ( (~valid_reg)&(~store_data) );
        end
    end


    reg [31:0] data_reg;
    wire store_data = ready_reg & master_valid & ~slave_ready;

    always @(posedge clk) begin
        if(rst) begin
            data_reg <= 32'd0;
        end
        else if(store_data)begin
            data_reg <= master_data; 
        end
    end


    reg valid_reg;
    always @(posedge clk) begin
        if(rst) begin
            valid_reg <= 1'b0;
        end
        else begin
            valid_reg <= valid_reg ? ~slave_ready : store_data;
        end
    end


    assign slave_data   = master_ready ? master_data  : data_reg  ; 
    assign slave_valid  = master_ready ? master_valid : valid_reg ; 
    assign master_ready = ready_reg;
endmodule





